package com.taxi.driver.data.amap;

import android.content.Context;
import android.text.TextUtils;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.maps.model.LatLng;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeAddress;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;
import com.socks.library.KLog;

import javax.inject.Inject;
import javax.inject.Singleton;

import rx.Observable;

@Singleton
public class AMapManager implements AMapSource {

    private final Context mContext;
    private AMapLocationClient mLocationClient;

    @Inject
    public AMapManager(Context context) {
        mContext = context;
    }

    @Override
    public AMapLocationClient getLocationClient() {
        mLocationClient = new AMapLocationClient(mContext);
        AMapLocationClientOption clientOption = new AMapLocationClientOption();
        clientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        clientOption.setInterval(4000);
        clientOption.setSensorEnable(true);
        mLocationClient.setLocationOption(clientOption);
        mLocationClient.startLocation();
        return mLocationClient;
    }

    @Override
    public AMapLocation getLastLocation() {
        if (mLocationClient == null) {
            mLocationClient = getLocationClient();
        }
        return mLocationClient.getLastKnownLocation();
    }

    @Override
    public void finishLocation() {
        if (mLocationClient != null) {
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }

    @Override
    public Observable<RegeocodeAddress> geocodeSearch(LatLng latLng) {
        return Observable.create(subscriber -> {
            GeocodeSearch geocodeSearch = new GeocodeSearch(mContext);
            RegeocodeQuery query = new RegeocodeQuery(
                    new LatLonPoint(latLng.latitude, latLng.longitude), 200, GeocodeSearch.AMAP);
            geocodeSearch.getFromLocationAsyn(query);
            geocodeSearch.setOnGeocodeSearchListener(new GeocodeSearch.OnGeocodeSearchListener() {
                @Override
                public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
                    if (rCode == 1000) {
                        if (result != null && result.getRegeocodeAddress() != null
                                && !TextUtils.isEmpty(result.getRegeocodeAddress().getCity())) {
                            subscriber.onNext(result.getRegeocodeAddress());
                            subscriber.onCompleted();
                        } else {
                            KLog.e("AMapManager#onRegeocodeSearched(): 未解析到地址信息");
                            subscriber.onError(new Throwable("未解析到地址信息"));
                        }
                    } else {
                        KLog.e("AMapManager#onRegeocodeSearched(): " + rCode);
                        subscriber.onError(new Throwable("解析地址失败"));
                    }
                }

                @Override
                public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

                }
            });
        });
    }

    @Override
    public Observable<DriveRouteResult> routeSearch(LatLonPoint start, LatLonPoint end) {
        return Observable.create(subscriber -> {
            RouteSearch routeSearch = new RouteSearch(mContext);
            RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(start, end);
            RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DRIVING_SINGLE_DEFAULT,
                    null, null, "");
            routeSearch.calculateDriveRouteAsyn(query);
            // 路线规划的回调
            routeSearch.setRouteSearchListener(new RouteSearch.OnRouteSearchListener() {
                @Override
                public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

                }

                @Override
                public void onDriveRouteSearched(DriveRouteResult result, int rCode) {
                    if (rCode == 1000) {
                        if (result != null && result.getPaths() != null && result.getPaths().size() > 0) {
                            subscriber.onNext(result);
                        } else {
                            subscriber.onError(new Throwable("对不起，没有搜索到相关数据！"));
                        }
                    } else if (rCode == 27) {
                        subscriber.onError(new Throwable("搜索失败,请检查网络连接！"));
                    } else if (rCode == 32) {
                        subscriber.onError(new Throwable("Key 验证无效！"));
                    } else {
                        subscriber.onError(new Throwable("未知错误，请稍后重试！错误码为" + rCode));
                    }
                }

                @Override
                public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

                }

                @Override
                public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

                }
            });
        });
    }
}
